using LocalBoard.Web.UserControls;

namespace LocalBoard.Web
{
	using System;
	using System.Collections;
	using System.Data;
	using System.Drawing;
	using System.IO;
	using System.Text.RegularExpressions;
	using System.Web;
	using System.Web.UI.WebControls;
	using System.Web.UI.HtmlControls;

	using LocalBoard.Domain;
	using LocalBoard.Controller;
	using LocalBoard.Persistence;

	/// <summary>
	///		Summary description for MessageView.
	/// </summary>
	public partial class MessageView : MessageUserControl
	{
		private int _totalVote = 0;

		//controls

		protected void Page_Load(object sender, System.EventArgs e)
		{
			if(!Page.IsPostBack)
			{
				if(LoadCurrentMessage())
				{
					if(!Convert.ToBoolean(Request.Params["post"]))
					{
						boardController.IncreaseHits(this.ClubUser, ref _currentMessage);
					}
					
					messageId.Text = _currentMessage.Id.ToString();
					if(_currentMessage.No > 0)
						messageNo.Text = _currentMessage.No.ToString();
					subjectDisplay.Text = GetDisplayText(_currentMessage.Subject);
					postedByName.Text = _currentMessage.PostedByUserName;
					postedByUserId.NavigateUrl = String.Format(postedByUserId.NavigateUrl, _currentMessage.PostedByUserId);
					postedByUserId.Text = _currentMessage.PostedByUserId;
					date.Text = _currentMessage.Date.ToString();
					numberOfView.Text = _currentMessage.Hits.ToString();
					if(_currentMessage.Attachments.Count > 0)
						attachments.DataSource = _currentMessage.Attachments;
					bodyDisplay.Text = GetDisplayText(_currentMessage.Body);
					shortMemoList.DataSource = _currentMessage.Comments;
					PollMessage pollMessage = _currentMessage as PollMessage;
					if(pollMessage != null)
					{
						PollMessageController pollManager = new PollMessageController(_currentMessage.Id, Global.AccessorFactory);
						if(pollManager.DidUserVote(this.ClubUser.Id))
						{
							pollResult.DataSource = pollMessage.PollItems;
							pollResult.Visible = true;

							foreach(PollItem item in pollMessage.PollItems)
							{
								_totalVote += item.NumberOfVotes;
							}
						}
						else
						{
							pollItemList.DataSource = pollMessage.PollItems;
							pollItemList.DataTextField = "Name";
							pollItemList.DataValueField = "Id";
							pollItemList.Visible = true;
							votePollBtn.Visible = true;
						}
					}
					
					DataBind();

					ProcessSecurityRelated();
				}
			
				if(_messageViewMode == "new")
				{
					if(_replyToMessageId > 0)
					{
						_replyToMessage = boardController.GetMessage(_replyToMessageId);
						subject.Text = "RE: " + _replyToMessage.Subject;
						body.Text = "\r\n\r\n\r\n=============== Original Message =================\r\n" + _replyToMessage.Body;
					}
					ChangeToEditMode();
				}
			}
			else
				rateArticle.Visible = false;
		}

		#region Helper
		private string GetDisplayText(string text)
		{
			return text.Replace("\r\n", "<br>");
		}
		private string GetEditText(string text)
		{
			return text.Replace("<br>", "\r\n");
		}
		private void ProcessSecurityRelated()
		{
			if(!boardController.GetBoardSecurity().CanUserEditMessage(this.ClubUser, _currentMessage))
				edit.Visible = false;
			if(!boardController.GetBoardSecurity().CanUserDeleteMessage(this.ClubUser, _currentMessage))
				delete.Visible = false;
			if(!boardController.GetBoardSecurity().CanUserPostReply(this.ClubUser))
				reply.Visible = false;

			if(!boardController.GetBoardSecurity().CanUserPostComment(this.ClubUser))
			{
				commentLabel.Visible = false;
				shortMemo.Visible = false;
				postShortMemo.Visible = false;
			}
		}
		private void ChangeToDisplayMode()
		{
			subject.Visible = false;
			subjectDisplay.Visible = true;
			body.Visible = false;
			bodyDisplay.Visible = true;
			shortMemoList.Visible = true;
			displayMode.Visible = true;
			editMode.Visible = false;
			msgHeadDisplay.Visible = true;
			msgHeadEdit.Visible = false;
		}
		private void ChangeToEditMode()
		{
			subject.Visible = true;
			subjectDisplay.Visible = false;
			body.Visible = true;
			bodyDisplay.Visible = false;
			shortMemoList.Visible = false;
			displayMode.Visible = false;
			editMode.Visible = true;
			msgHeadDisplay.Visible = false;
			msgHeadEdit.Visible = true;
		}
		#endregion

		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		///		Required method for Designer support - do not modify
		///		the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.attachments.ItemDataBound += new System.Web.UI.WebControls.RepeaterItemEventHandler(this.attachments_DataBound);
			this.pollResult.ItemDataBound += new System.Web.UI.WebControls.RepeaterItemEventHandler(this.pollResult_ItemDataBound);
			this.shortMemoList.ItemDataBound += new System.Web.UI.WebControls.RepeaterItemEventHandler(this.shortMemoList_ItemDataBound);

		}
		#endregion

		#region Event Handler
		protected void Edit_Click(object sender, System.EventArgs e)
		{
			SetMessageId(Convert.ToInt32(messageId.Text));
			LoadCurrentMessage();
			subject.Text = GetEditText(_currentMessage.Subject);
			body.Text = GetEditText(_currentMessage.Body);
			ChangeToEditMode();
		}
		protected void PostMessage_Click(object sender, System.EventArgs e)
		{
			string subjectStr = Security.GetCleanUserInput(subject.Text);
			string bodyStr = Security.GetCleanUserInput(body.Text);
			int redirectMessageId = 0;
			if(_messageViewMode == "new")
			{
				if(subjectStr.Length > 0)
				{
					if(Request.Params["attachpollyn"] == "Y" && Request.Params["attachpolls"].Length > 0)
					{
						redirectMessageId = boardController.PostPollMessage(subjectStr, bodyStr, this.ClubUser, _replyToMessageId);
						PollMessageController messageController = new PollMessageController(redirectMessageId, Global.AccessorFactory);

						char[] delimeter = {'|'};
						foreach(string pollItem in Request.Params["attachpolls"].Split(delimeter))
						{
							messageController.AddPollItem(new PollItem(pollItem));
						}
						messageController = null;
					}
					else
						redirectMessageId = boardController.PostMessage(subjectStr, bodyStr, this.ClubUser, _replyToMessageId);

					if(Request.Params["attachfiles"].Length > 0)
					{
						MessageController messageController = new MessageController(redirectMessageId, Global.AccessorFactory);
						foreach(Attachment attachment in GetAttachmentList(Request.Params["attachfiles"], Request.Params["attachsizes"]))
						{
							messageController.UploadAttachment(attachment);
						}
					}
				}
				else
				{
					throw new Exception("Subject in new Message should not be blank");
				}
			}
			else
			{
				_currentMessage = boardController.GetMessage(Convert.ToInt32(messageId.Text));
				if(subjectStr != _currentMessage.Subject
					|| bodyStr != _currentMessage.Body)
					boardController.EditMessage(_currentMessage, subjectStr, bodyStr);
				redirectMessageId = _currentMessage.Id;
			}
			Response.Redirect(CurrentBoardPageUrl + "&message=" + redirectMessageId.ToString() +"&post=true");
		}
		private ArrayList GetAttachmentList(string attachfiles, string attachsizes)
		{
			ArrayList attachmentList = new ArrayList();
			char[] fileSeparator = new char[1] {'|'};
			char[] fileInfoSeparator = new char[1] {';'};
			string[] files = attachfiles.Split(fileSeparator);
			string[] fileSizes = attachsizes.Split(fileSeparator);
			int index = 0;
			if(files.Length == fileSizes.Length)
			{
				foreach(string eachfile in files)
				{
					if(eachfile.Length > 0)
					{
						string[] fileInfo = eachfile.Split(fileInfoSeparator);
						attachmentList.Add(new Attachment(GetFileNameFromWebPath(fileInfo[0]), int.Parse(fileSizes[index]), fileInfo[0]));
					}
					index++;
				}
			}
			return attachmentList;
		}
		private string GetFileNameFromWebPath(string webPath)
		{
			char[] webPathSeparator = new char[1] {'/'};
			string[] splitted = webPath.Split(webPathSeparator);
			return splitted[splitted.Length - 1];
		}
		protected void Reply_Click(object sender, System.EventArgs e)
		{
			Response.Redirect(CurrentBoardPageUrl + "&mode=new&replyto=" + messageId.Text);
		}
		protected void postShortMemo_Click(object sender, System.EventArgs e)
		{
			string commentBody = Security.GetCleanUserInput(shortMemo.Text);
			if(commentBody.Length > 0)
				messageController.PostComment(commentBody, this.ClubUser);
			Response.Redirect(CurrentBoardPageUrl + "&message=" + messageId.Text + "&post=true");
		}
		private void shortMemoList_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
		{
			if (e.Item.DataItem != null
				&& (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item))
			{
				ImageButton shortMemoDelete = e.Item.FindControl("shortMemoDelete") as ImageButton;
				Literal shortMemoBody = e.Item.FindControl("shortMemoBody") as Literal;
				Label shortMemoPostedByName = e.Item.FindControl("shortMemoPostedByName") as Label;
				Label shortMemoPostedById = e.Item.FindControl("shortMemoPostedById") as Label;
				Label shortMemoDate = e.Item.FindControl("shortMemoDate") as Label;

				Comment comment = e.Item.DataItem as Comment;

				if(comment == null) return;
				if(shortMemoDelete != null)
				{
					shortMemoDelete.Attributes.Add("ShortMemoId", comment.Id.ToString());
					if(!boardController.GetBoardSecurity().CanUserDeleteComment(this.ClubUser, comment))
						shortMemoDelete.Visible = false;
				}
				if(shortMemoBody != null)
					shortMemoBody.Text = comment.Body;
				if(shortMemoPostedByName != null)
					shortMemoPostedByName.Text = comment.PostedByUserName;
				if(shortMemoPostedById != null)
					shortMemoPostedById.Text = comment.PostedByUserId;
				if(shortMemoDate != null)
					shortMemoDate.Text = comment.Date.ToString();
			}
		}
		protected void shortMemoDelete_Click(object sender, System.Web.UI.ImageClickEventArgs e)
		{
			ImageButton button = sender as ImageButton;
			messageController.DeleteComment(Convert.ToInt32(button.Attributes["ShortMemoId"]));
			Response.Redirect(CurrentBoardPageUrl + "&message=" + messageId.Text + "&post=true");
		}
		protected void delete_Click(object sender, System.EventArgs e)
		{
			boardController.DeleteMessage(Convert.ToInt32(messageId.Text));
			Response.Redirect(CurrentBoardPageUrl);
		}
		#endregion

		private void attachments_DataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
		{
			if(e.Item == null) return;
			if(e.Item.ItemType == ListItemType.Item
				|| e.Item.ItemType == ListItemType.AlternatingItem)
			{
				HyperLink attachLink = e.Item.FindControl("attachLink") as HyperLink;
				Attachment attachment = e.Item.DataItem as Attachment;
				if(attachLink != null && attachment != null)
				{
					attachLink.NavigateUrl = attachment.Path;
					attachLink.Text = attachment.Name;
				}
			}
		}

		protected void votePollBtn_Click(object sender, System.EventArgs e)
		{
			PollMessageController pollManager = new PollMessageController(Int32.Parse(messageId.Text), Global.AccessorFactory);
			pollManager.PostPoll(this.ClubUser.Id, Int32.Parse(pollItemList.SelectedValue));
			Response.Redirect(CurrentBoardPageUrl + "&message=" + messageId.Text);
		}

		private void pollResult_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
		{
			if(e.Item == null) return;
			if(e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
			{
				Label pollItemName = e.Item.FindControl("pollItemName") as Label;
				Label votedPercentage = e.Item.FindControl("votedPercentage") as Label;
				PollItem pollItem = e.Item.DataItem as PollItem;
				if(pollItemName != null)
					pollItemName.Text = pollItem.Name;
				if(votedPercentage != null)
				{
					double percentage = pollItem.NumberOfVotes / _totalVote;
					votedPercentage.Text = percentage.ToString("0.0%");
				}
			}
		}
	}
}
